package com.mars.common.utils;

import com.ag.exception.SysTipsException;
import com.ag.utils.NumberUtils;
import com.alibaba.fastjson.JSONObject;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Path;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections.MapUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;

import java.util.Map;

/**
 * 
 * title: PageVo.java 
 *
 * @author rplees
 * @email rplees.i.ly@gmail.com
 * @version 1.0  
 * @created Jan 6, 2021 6:15:40 PM
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PageParam {
	@Builder.Default
    public Integer pageNum = 1;
	@Builder.Default
    public Integer pageSize = 15;
    
	public static Pageable of(PageParam p, Sort sort) {
    	if(p == null) {
    		p = new PageParam();
    	}
		return of(p.pageNum, p.pageSize, sort);
    }
	
    public static Pageable of(PageParam p, Direction direction, String... properties) {
    	if(p == null) {
    		p = new PageParam();
    	}
		return of(p.pageNum, p.pageSize, Sort.by(direction, properties));
    }
    
    @SuppressWarnings("rawtypes")
	public static Pageable of(PageParam p, OrderSpecifier<?> desc) {
		Direction d = Direction.ASC;
		if(! desc.isAscending()) {
			d = Direction.DESC;
		}
		String prop = null;
		Expression<?> target = desc.getTarget();
		if(target instanceof Path) {
			prop = ((Path) target).getMetadata().getElement().toString();
		} else {
			throw new SysTipsException("请实现Pageable.of的更新情况");
		}
		return of(p, Sort.by(d, prop));
	}
    
    public static Pageable of(PageParam p) {
    	if(p == null) {
    		p = new PageParam();
    	}
    	return of(p.pageNum, p.pageSize);
    }
    
    @SuppressWarnings("rawtypes")
	public static Pageable of(Map param) {
		return of(MapUtils.getInteger(param, "pageNum"), MapUtils.getInteger(param, "pageSize"));
	}
	
	public static Pageable of(JSONObject j) {
		return of(j.getInteger("pageNum"), j.getInteger("pageSize"));
	}
	
	public static Pageable of(int pageNum, int pageSize) {
		return of(pageNum, pageSize, null);
	}
	
	public static Pageable of(int pageNum, int pageSize, Sort sort) {
		if(NumberUtils.isNotValid(pageNum)) {
			pageNum = 1;
		}
		
		if(NumberUtils.isNotValid(pageSize)) {
			pageSize = 15;
		}
		
		pageNum -=1; //springboot分页的索引是从0开始的
		if(sort != null) {
			return PageRequest.of(pageNum, pageSize, sort);
		} else {
			return PageRequest.of(pageNum, pageSize);
		}
	}
}
